package com.kr.weitao.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by lide on 2017/9/7.
 */
public class ExportFile {
  static String save_file_path = "/tmp/";
  /**
   *
   * @param fileData 数据
   * @param colNames 字段名
   * @param user_id   用户id
   * @param titleName 字段显示名
   * @return
   */
  public static JSONObject exportFile(
          JSONArray fileData, String[] colNames, String user_id, String[] titleName) {
    String path = save_file_path;
    //转换表格列名，得到数据库对应名称
    JSONObject input_object = new JSONObject();
    InputStream is = null;
    try {
      //分割导出内容
      JSONArray data_array = cutArray(fileData);
      if (data_array.size() > 0) {
        List<File> srcfile = new ArrayList<>();
        for (int i = 0; i < data_array.size(); i++) {
          JSONArray data = data_array.getJSONArray(i);

          ByteArrayOutputStream byteArray = saveFile(data, colNames, titleName);
          String save_path = path + fileName() + ".csv";
          File file = new File(save_path);
          if (!file.exists()) {
            file.createNewFile();
            DataOutputStream to = new DataOutputStream(new FileOutputStream(file));
            byteArray.writeTo(to);
            srcfile.add(file);
          }
        }
        if (srcfile.size() > 0) {
          String zip_path = path + "ZIP" + user_id + "-" + fileName() + ".zip";
          File zipfile = new File(zip_path);
          if (!zipfile.exists()) {
            is = new FileInputStream(zipFiles(srcfile, zipfile));
            input_object.put("file_name", zipfile.getName());
            input_object.put("file_input", is);
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return input_object;
  }

  public static JSONArray cutArray(JSONArray array) throws Exception {
    int blockSize = 30000;

    JSONArray arrays = new JSONArray();
    if (null != array && blockSize > 0) {
      int listSize = array.size();
      if (listSize <= blockSize) {
        arrays.add(array);
        return arrays;
      }
      int batchSize = listSize / blockSize;
      int remain = listSize % blockSize;
      for (int i = 0; i < batchSize; i++) {
        int fromIndex = i * blockSize;
        int toIndex = fromIndex + blockSize;
        arrays.add(array.subList(fromIndex, toIndex));
      }
      if (remain > 0) {
        arrays.add(array.subList(listSize - remain, listSize));
      }
    }
    return arrays;
  }

  /**
   * 创建文件
   *
   * @param fileData 文件内容
   * @param colNames 标题名称
   * @return
   */
  public static ByteArrayOutputStream saveFile(JSONArray fileData, String[] colNames, String[] titleName) {

    SXSSFWorkbook wb = null;
    try {
      List<Object[]> excelContent = new LinkedList<>();
      if (fileData.size() > 0) {

        //处理JSONArayy，得到表格内容
        for (int i = 0; i < fileData.size(); i++) {
          JSONObject details_object = fileData.getJSONObject(i);
          String form_key[] = new String[colNames.length];
          if (details_object.size() > 0) {
            for (int k = 0; k < colNames.length; k++) {
              String key = colNames[k].trim();
              String value = "";
              if (org.apache.commons.lang.StringUtils.isNotBlank(key)) {
                if (details_object.containsKey(key)) {
                  value = details_object.getString(key);
                  form_key[k] = value;
                }
              }
            }
          }
          if (form_key.length > 0 && !form_key.equals("")) {
            excelContent.add(form_key);
          }
        }
      }
      ByteArrayOutputStream os = new ByteArrayOutputStream();
      wb = new SXSSFWorkbook();
      SXSSFSheet sheet = wb.createSheet();
      //创建Excel列表头的名称
      if (!titleName.equals("") && titleName.length > 0) {
        creaTableName(sheet, titleName);
      }
      //创建Excel列表nro
      if (excelContent.size() > 0) {
        createExcelContent(sheet, excelContent);
      }
      wb.write(os);
      return os;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (wb != null) {
        try {
          wb.close();
          wb = null;
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return null;
  }

  /**
   * 创建文件标题
   *
   * @param sheet
   * @param name
   */
  public static void creaTableName(SXSSFSheet sheet, String[] name) {
    int count = name.length;
    SXSSFRow colRow = sheet.createRow(0);
    for (int i = 0; i < count; i++) {
      SXSSFCell cell = colRow.createCell(i, SXSSFCell.CELL_TYPE_STRING);
      cell.setCellValue(new XSSFRichTextString(name[i].trim()));
    }
  }

  /**
   * 创建文件内容
   *
   * @param sheet
   * @param datalist
   */
  public static void createExcelContent(SXSSFSheet sheet, List<Object[]> datalist) {
    int startIndex = sheet.getLastRowNum() + 1;
    for (int i = 0; i < datalist.size(); i++) {
      SXSSFRow colRow = sheet.createRow(startIndex + i);
      Object[] datas = datalist.get(i);
      if (null != datas && datas.length > 0) {
        for (int j = 0; j < datas.length; j++) {
          SXSSFCell cell = colRow.createCell(j, SXSSFCell.CELL_TYPE_STRING);
          if (null != datas[j] && !datas[j].equals("")) {
            cell.setCellValue(new XSSFRichTextString(datas[j].toString()));
          }
        }
      }
    }
  }
  /**
   * 生成文件名称
   *
   * @return
   */
  public static String fileName() {
    String fileName = "";
    String time = TimeUtils.getTime(new Date().getTime(), TimeUtils.DATETIME_FORMAT_DATE_NO);
    String random = StringUtils.randomNumber(6);
    fileName = time + random;
    return fileName;
  }
  /**
   * 将多个文件打包成zip文件
   *
   * @param srcfile
   */
  public static File zipFiles(List<File> srcfile, File zipfile) {
    byte[] buf = new byte[1024];
    try {
      ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile));
      for (int i = 0; i < srcfile.size(); i++) {
        File file = srcfile.get(i);
        FileInputStream in = new FileInputStream(file);
        out.putNextEntry(new ZipEntry(file.getName()));
        int len;
        while ((len = in.read(buf)) > 0) {
          out.write(buf, 0, len);
        }
        out.closeEntry();
        in.close();
      }
      out.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return zipfile;
  }
}
